package com.chenfan.process.biz.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chenfan.ccp.common.exception.ApiException;
import com.chenfan.process.biz.ApprovalFormBiz;
import com.chenfan.process.common.exception.ProcessResultCode;
import com.chenfan.process.entity.dto.FormDTO;
import com.chenfan.process.entity.dto.FormQueryDTO;
import com.chenfan.process.entity.po.ProcessForm;
import com.chenfan.process.entity.po.ProcessFormAttribute;
import com.chenfan.process.entity.validator.ProcessFormVO;
import com.chenfan.process.enums.BooleanEnum;
import com.chenfan.process.service.ProcessFormAttributeService;
import com.chenfan.process.service.ProcessFormService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author liuming
 * @date 2021/11/24
 */
@Service
public class ApprovalFormBizImpl implements ApprovalFormBiz {

    @Autowired
    private ProcessFormService processFormService;
    @Autowired
    private ProcessFormAttributeService processFormAttributeService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long saveForm(FormDTO form) {
        // 检查是否已经存在相同的表单名称.
        ProcessForm checkForm = processFormService.getByFormName(form.getFormName());
        if (checkForm != null) {
            throw new ApiException(ProcessResultCode.FORM_EXISTS);
        }
        // 保存表单
        ProcessForm processForm = ProcessForm.ofDefault(form.getFormName());
        processForm.setContent(form.getContent());
        processForm.setIcon(form.getIcon());
        processFormService.save(processForm);
        // 保存表单属性
        List<FormDTO.FormAttribute> formAttributes = form.getFormAttributes();
        if (CollectionUtils.isEmpty(formAttributes)) {
            throw new ApiException(ProcessResultCode.NOT_EMPTY);
        }

        List<ProcessFormAttribute> processFormAttributes = formAttributes.stream().map(e -> {
            ProcessFormAttribute processFormAttribute = ProcessFormAttribute.ofDefault(e);
            processFormAttribute.setFormId(processForm.getId());
            return processFormAttribute;
        }).collect(Collectors.toList());

        processFormAttributeService.saveBatch(processFormAttributes);
        return processForm.getId();
    }

    @Override
    public Long updateForm(FormDTO form) {
        ProcessForm processForm = getAndCheck(form.getId());
        processForm.setFormName(form.getFormName());
        processForm.setContent(form.getContent());
        processForm.setIcon(form.getIcon());
        processForm.updateSelf();
        // 更新表单
        processFormService.updateById(processForm);

        List<ProcessFormAttribute> processFormAttributes =
            processFormAttributeService.listByFormId(processForm.getId());
        processFormAttributes = processFormAttributes.stream().peek(e -> e.setDeletedFlag(BooleanEnum.Y.getCode()))
            .collect(Collectors.toList());
        processFormAttributeService.updateBatchById(processFormAttributes);
        List<FormDTO.FormAttribute> formAttributes = form.getFormAttributes();

        // 之前的设置为删除状态.
        List<ProcessFormAttribute> formAttributeList = formAttributes.stream().map(e -> {
            ProcessFormAttribute attribute = ProcessFormAttribute.ofDefault(e);
            attribute.setFormId(processForm.getId());
            return attribute;
        }).collect(Collectors.toList());
        processFormAttributeService.saveBatch(formAttributeList);
        return processForm.getId();
    }

    @Override
    public void changeStatus(Long formId, Integer status) {
        ProcessForm processForm = getAndCheck(formId);
        processForm.setStatus(status);
        processForm.updateSelf();
        processFormService.updateById(processForm);
    }

    @Override
    public void removeForm(Long formId) {
        ProcessForm processForm = getAndCheck(formId);
        if (processForm.isAvailable()) {
            // throw new ApiException(ProcessResultCode.);
        }
        // 检查表单状态. 只有被禁用的状态下才能被删除.
        processForm.setDeletedFlag(BooleanEnum.Y.getCode());
        processFormService.updateById(processForm);
    }

    @Override
    public ProcessFormVO formDetail(Long formId) {
        ProcessForm processForm = getAndCheck(formId);
        List<ProcessFormAttribute> processFormAttributes =
            processFormAttributeService.listByFormId(processForm.getId());
        return ProcessFormVO.builder().processForm(processForm).processFormAttributes(processFormAttributes).build();
    }

    private ProcessForm getAndCheck(Long formId) {

        ProcessForm processForm = processFormService.getById(formId);
        if (Objects.isNull(processForm)) {
            throw new ApiException(ProcessResultCode.FORM_NOT_FOUND);
        }
        return processForm;
    }

    @Override
    public Page<ProcessForm> page(Integer pageNum, Integer pageSize, FormQueryDTO form) {
        return processFormService.pageProcessForm(form, pageNum, pageSize);
    }
}
